﻿
#ifndef ModelBoneCollection_h
#define ModelBoneCollection_h

#include <System/Collections/Generic/IReadOnlyCollection.h>
#include <System/Collections/Generic/RKeyNotFoundException.h>
#include <System/Collections/ObjectModel/RReadOnlyCollection.h>

#include <Riccsson/Xna/Framework/RMatrix.h>
#include <Riccsson/Xna/Framework/Graphics/ModelBone.h>

namespace Riccsson
{
	namespace Xna
	{
		namespace Framework
		{
			namespace Graphics
			{
				// Summary:
				//     Represents a set of bones associated with a model.
				class ModelBoneCollection
					: public Riccsson::System::Collections::ObjectModel::ReadOnlyCollection<GC_PTR<ModelBone>>
				{
					public: ModelBoneCollection(Riccsson::System::Collections::Generic::IList<GC_PTR<ModelBone>>* list)
						: Riccsson::System::Collections::ObjectModel::ReadOnlyCollection<GC_PTR<ModelBone>>(list)
					{

					}

					// Summary:
					//     Retrieves a ModelBone from the collection, given the name of the bone.
					//
					// Parameters:
					//   boneName:
					//     The name of the bone to retrieve.
					public: GC_PTR<ModelBone> operator[](Riccsson::System::string* boneName)
					{
						GC_PTR<ModelBone> ret;
						if (TryGetValue(boneName, /*out*/ **ret))
						{
							return ret;
						}
						throw Riccsson::System::Collections::Generic::KeyNotFoundException();
					}

					//    // Summary:
					//    //     Returns a ModelBoneCollection.Enumerator that can iterate through a ModelBoneCollection.
					//    public: ModelBoneCollection.Enumerator GetEnumerator() { throw new NotImplementedException(); }

					//
					// Summary:
					//     Finds a bone with a given name if it exists in the collection.
					//
					// Parameters:
					//   boneName:
					//     The name of the bone to find.
					//
					//   value:
					//     [OutAttribute] The bone named boneName, if found.
					public: bool TryGetValue(Riccsson::System::string* boneName, GC_PTR<ModelBone> out value)
					{
						foreach (ModelBone* bone : (***this->Items))
						{
							if (bone->Name == boneName)
							{
								value = bone;
								return true;
							}
						}
						value = null;
						return false;
					}
				};
			}
		}
	}
}

#endif